package com.histone.grab_ticket.service;

import com.histone.grab_ticket.entity.TicketEntity;
import com.histone.grab_ticket.repo.TicketDao;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.CountDownLatch;

@Service
@Slf4j
public class TicketService {
    @Autowired
    private TicketDao ticketDao;

    @Autowired
    private StringRedisTemplate template;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private CountDownLatch latch;

    public Boolean grabTicket(String ticketid, String userid) {
        boolean result = false;
        RLock lock = redissonClient.getLock("lock-" + ticketid);
        try {
            lock.lock();
            String ticketVal = template.opsForValue().get("ticket-" + ticketid);
            if (StringUtils.isEmpty(ticketVal)) {
                // redis中没有该工单，查询MongoDB
                TicketEntity ticketEntity = ticketDao.findById(ticketid).get();
                if(StringUtils.isEmpty(ticketEntity.getContact())) {
                    template.opsForValue().set("ticket-" + ticketid, userid);
                    template.convertAndSend("ticket", ticketid);
                    result = true;
                    log.info("{} get ticket {} successful", userid, ticketid);
                }
            } else if("nobody".equalsIgnoreCase(ticketVal)){
                template.opsForValue().set("ticket-" + ticketid, userid);
                template.convertAndSend("ticket", ticketid);
                result = true;
                log.info("{} get ticket {} successful", userid, ticketid);
            } else {
                log.info("{} get ticket {} failed, it belong to {}", userid, ticketid, ticketVal);
            }
        } catch (Exception ex) {
            log.error("{} grab ticket {} error occurred, {}", userid, ticketid, ex.getMessage());
            ex.printStackTrace();
        } finally {
            lock.unlock();
        }

        return result;
    }
    //接收redis队列消息
    public void receiveMessage(String message) {
        // ticket 不存在 直接报错
        TicketEntity ticket = ticketDao.findById(message).get();
        // 修改后保存
        ticket.setContact(template.opsForValue().get("ticket-" + message));
        ticketDao.save(ticket);

        latch.countDown();
    }



    public TicketEntity save(TicketEntity ticket) {
        return ticketDao.save(ticket);
    }

    public TicketEntity getTicketById(String id){
        return ticketDao.findById(id).orElse(null);
    }

    public List<TicketEntity> getTicektByContact(String contact) {
        return ticketDao.findByContact(contact);
    }
}
